/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.edu.agh.administracja.networkconfig.controller;

import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.lang.reflect.Field;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import pl.edu.agh.administracja.networkconfig.model.IpV4Address;

/**
 * Aktualizuje model przy zmianie adresu. Jesli wprowadzony adres jest
 * niepoprawny to zwraca blad.
 *
 * @author piotrek
 */
public class AddressChangedListener implements FocusListener {
    public static final int MAX_ADDRESS_PART_NUMBER = 255;
    
    private JTextField textField;
    private Object object;
    private String varName;
    private boolean mask;

    public AddressChangedListener(JTextField textField, Object object, String varName, boolean mask) {
        this.textField = textField;
        this.object = object;
        this.varName = varName;
        this.mask = mask;
    }

    @Override
    public void focusGained(FocusEvent fe) {
        // nothing to do
    }

    @Override
    public void focusLost(FocusEvent fe) {

        String[] parts = textField.getText().split("\\.");

        if (textField.getText().isEmpty()) {
            setValue(null);
            return;
        }

        if(!Pattern.matches(IpV4Address.ADDRESS_PATTERN, textField.getText())){
            showError();
                return;
        }
        
        boolean zeroOccured = false;

        for (int i = 0; i < IpV4Address.ADDRESS_LENGTH; i++) {
            if (parts[i].isEmpty() || Integer.parseInt(parts[i]) > MAX_ADDRESS_PART_NUMBER) {
                showError();
                return;
            }

            if (mask) {
                int val = Integer.parseInt(parts[i]);
                String str = Integer.toBinaryString(val);

                Pattern pattern = Pattern.compile((zeroOccured ? "" : "([1]*)") + "([0]*)");
                Matcher matcher = pattern.matcher(str);
                
                if(!matcher.matches()){
                    showError();
                    return;
                }
                
                if(!zeroOccured && !matcher.group(2).isEmpty())
                    zeroOccured = true;
            }

        }
        
        setValue(IpV4Address.fromString(textField.getText()));
    }

    private void showError() {
        String err = mask ? "Wprowadz poprawna maske" : "Wprowadz poprawny adres";
        JOptionPane.showMessageDialog(textField, err, "Error", JOptionPane.ERROR_MESSAGE);
        textField.requestFocus();
    }

    private void setValue(IpV4Address address) {
        try {
            Field field = object.getClass().getDeclaredField(varName);
            field.setAccessible(true);
            field.set(object, address);
        } catch (Exception ex) {
            Logger.getLogger(AddressChangedListener.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
